#/usr/bin/python27
#-*- coding: utf-8 -*-
#  Copyright 2011-2013 wuweihui@cn.ibm.com
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

import sys
import re
import random
import unittest
from CIMConnection.CIMlib import *
from comm.loglib import *
from cimsupport import *


def setUpModule():
   #connect_to_win()
   ##Discover at level 2
#   start_discovery(level=2, force=True)
#   ret = wait_until_discovery_finish(5*60)
#   if ret.status != '0':
#      raise RuntimeError("Discovery Failed!")
   #close_all_connections()
   pass
   
def tearDownModule():
   pass

class MSVolumeTest(unittest.TestCase):
    # 
    
    @classmethod
    def setUpClass(self):
       connect_to_win()
       
       self.volprefix = generate_vol_prefix()
       self.poollist = get_pool_sizes()
       self.vollist = []
       self.system = ms_enumerate("MSFT_SMSystem")[0]
       close_all_connections()
      
    @classmethod
    def tearDownClass(self):
       for vol in self.vollist:
          try:
             ms_remove_vol(vol)
          except:
             pass
       close_all_connections()
      
    def setUp(self):
       connect_to_win()
   
    def tearDown(self):
       raiseflag = False
       while self.vollist:
          vol = self.vollist.pop()
          try:
             ms_remove_vol(vol)
          except:
             raiseflag = True
       close_all_connections()
       if raiseflag:
          raise 
       
    @unittest.skip("demonstrating skipping")
    def test_nothing(self):
        self.fail("shouldn't happen")
        
    def test_create_pool_volume(self):
       """
       cpsv or createPoolStorageVolume <srcPool-objID> <elementName> <new-size-in-bytes> 
       <nosinglepointoffailure(0=false,1=true)> <packageredundancygoal> <dataredundancygoal> 
       <paritylayout> [[user name] [pwd|!]]
       """
       log("test_create_pool_volume")
       volname = self.volprefix+gen_vol_id()
       volsize = get_pool_size_division(self.poollist[0])
       poolsize = ms_get_sizes_info(self.poollist[0]).MaximumVolumeSize
       ret = exec_ms_cmd_ex('createPoolStorageVolume', self.poollist[0].ObjectId, volname, 
                            volsize, 'true', '1', '2', '')
       self.assertEqual(ret.ReturnValue, '0', "Volume Creation Failure! Return code not right!")
       
       ret = check_volume_in_system(volname)
       self.assertTrue(ret[0], ret[1])
       self.vollist.append(ret[0])
       self.assertEqual(long(ms_get_sizes_info(self.poollist[0]).MaximumVolumeSize), long(poolsize) - long(volsize))
       
    def test_create_storage_volume(self):
       """
       cssv or createSystemStorageVolume <system-objID><elementName>
       <new-size-in-bytes><nosinglepointoffailure(0=false,1=true)>
       <packageredundancygoal><dataredundancygoal><paritylayout> [[user name] [pwd|!]]
       """
       log("test_create_storage_volume")
       volname = self.volprefix+gen_vol_id()
       ret = exec_ms_cmd_ex('createSystemStorageVolume', self.system.ObjectId, volname, 
                            get_pool_size_division(self.poollist[0]), 'true', '1', '2', '')
       self.assertEqual(ret.ReturnValue, '0', "Volume Creation Failure! Return code not right!")
       
       ret = check_volume_in_system(volname)
       self.assertTrue(ret[0], ret[1])
       self.vollist.append(ret[0])
       
    def test_create_pool_volume_with_maximum_size(self):
       """
       cpsv or createPoolStorageVolume <srcPool-objID> <elementName> <new-size-in-bytes> 
       <nosinglepointoffailure(0=false,1=true)> <packageredundancygoal> <dataredundancygoal> 
       <paritylayout> [[user name] [pwd|!]]
       """
       log("test_create_pool_volume_with_maximum_size")
       volname = self.volprefix+gen_vol_id()
       poolsize = ms_get_sizes_info(self.poollist[0]).MaximumVolumeSize
       volsize = poolsize
       ret = exec_ms_cmd_ex('createPoolStorageVolume', self.poollist[0].ObjectId, volname, 
                            volsize, 'true', '1', '2', '')
       self.assertEqual(ret.ReturnValue, '0', "Volume Creation Failure! Return code not right!")
       
       ret = check_volume_in_system(volname)
       self.assertTrue(ret[0], ret[1])
       self.vollist.append(ret[0])
       self.assertEqual(long(ms_get_sizes_info(self.poollist[0]).MaximumVolumeSize), long(poolsize) - long(volsize))
       
       volname = self.volprefix+gen_vol_id()
       poolsize = ms_get_sizes_info(self.poollist[1]).MaximumVolumeSize
       volsize = poolsize
       ret = exec_ms_cmd_ex('createSystemStorageVolume', self.system.ObjectId, volname, 
                            volsize, 'true', '1', '2', '')
       self.assertEqual(ret.ReturnValue, '0', "Volume Creation Failure! Return code not right!")
       
       ret = check_volume_in_system(volname)
       self.assertTrue(ret[0], ret[1])
       self.vollist.append(ret[0])
       
    def test_create_pool_volume_with_minimum_size(self):
       """
       cpsv or createPoolStorageVolume <srcPool-objID> <elementName> <new-size-in-bytes> 
       <nosinglepointoffailure(0=false,1=true)> <packageredundancygoal> <dataredundancygoal> 
       <paritylayout> [[user name] [pwd|!]]
       """
       log("test_create_pool_volume_with_minimum_size")
       volname = self.volprefix+gen_vol_id()
       poolsizeinfo = ms_get_sizes_info(self.poollist[0])
       poolsize = poolsizeinfo.MaximumVolumeSize
       volsize = poolsizeinfo.MinimumVolumeSize
       ret = exec_ms_cmd_ex('createPoolStorageVolume', self.poollist[0].ObjectId, volname, 
                            volsize, 'true', '1', '2', '')
       self.assertEqual(ret.ReturnValue, '0', "Volume Creation Failure! Return code not right!")
       
       ret = check_volume_in_system(volname)
       self.assertTrue(ret[0], ret[1])
       self.vollist.append(ret[0])
       self.assertEqual(long(ms_get_sizes_info(self.poollist[0]).MaximumVolumeSize), long(poolsize) - long(volsize))
       
    def test_create_pool_volume_exceed_maximum_size(self):
       """
       cpsv or createPoolStorageVolume <srcPool-objID> <elementName> <new-size-in-bytes> 
       <nosinglepointoffailure(0=false,1=true)> <packageredundancygoal> <dataredundancygoal> 
       <paritylayout> [[user name] [pwd|!]]
       """
       log("test_create_pool_volume_exceed_maximum_size")
       volname = self.volprefix+gen_vol_id()
       poolsizeinfo = ms_get_sizes_info(self.poollist[0])
       poolsize = poolsizeinfo.MaximumVolumeSize
       volsize = str(long(poolsize) + 1)
       ret = exec_ms_cmd_ex('createPoolStorageVolume', self.poollist[0].ObjectId, volname, 
                            volsize, 'true', '1', '2', '')
       if ret.ReturnValue == '0':
          ckret = check_volume_in_system(volname)
          if ckret[0]:
             self.vollist.append(ckret[0])
       self.assertEqual(ret.ReturnValue, '4097', "Volume Creation Failure! Return code not right!")
       
       ret = check_volume_in_system(volname)
       self.assertFalse(ret[0], ret[1])
       
    def test_create_pool_volume_less_than_minimum_size(self):
       """
       cpsv or createPoolStorageVolume <srcPool-objID> <elementName> <new-size-in-bytes> 
       <nosinglepointoffailure(0=false,1=true)> <packageredundancygoal> <dataredundancygoal> 
       <paritylayout> [[user name] [pwd|!]]
       """
       log("test_create_pool_volume_less_than_minimum_size")
       volname = self.volprefix+gen_vol_id()
       poolsizeinfo = ms_get_sizes_info(self.poollist[0])
       poolsize = poolsizeinfo.MaximumVolumeSize
       volsize = str(long(poolsizeinfo.MinimumVolumeSize)/2)
       ret = exec_ms_cmd_ex('createPoolStorageVolume', self.poollist[0].ObjectId, volname, 
                            volsize, 'true', '1', '2', '')
       self.assertEqual(ret.ReturnValue, '0', "Volume Creation Failure! Return code not right!")
       
       ret = check_volume_in_system(volname)
       self.assertTrue(ret[0], ret[1])
       self.vollist.append(ret[0])
       self.assertEqual(long(ms_get_sizes_info(self.poollist[0]).MaximumVolumeSize), long(poolsize) - long(poolsizeinfo.MinimumVolumeSize))
       
       log("Check pool size should be the same after this volume reomved from system")
       ms_remove_vol(ret[0])
       self.assertEqual(long(ms_get_sizes_info(self.poollist[0]).MaximumVolumeSize), long(poolsize))
       
    def test_delete_volume_by_id(self):
       """
       dsv or deleteStorageVolume <stgVolume-objID|stgVolume-ref|stgVolume-name> [[user name] [pwd|!]]
       """
       log("test_delete_volume_by_id")
       volname = self.volprefix+gen_vol_id()
       vol = ms_create_vol(volname=volname, system=self.system)
       ret = exec_ms_cmd_ex('deleteStorageVolume', vol.ObjectId)
       self.assertEqual(ret.ReturnValue, '0', "Volume Delete Failure! Return code not right!")
       
       ret = check_volume_in_system(volname)
       self.assertFalse(ret[0], ret[1])
       
    def test_delete_volume_by_name(self):
       """
       dsv or deleteStorageVolume <stgVolume-objID|stgVolume-ref|stgVolume-name> [[user name] [pwd|!]]
       """
       log("test_delete_volume_by_name")
       volname = self.volprefix+gen_vol_id()
       vol = ms_create_vol(volname=volname, system=self.system)
       ret = exec_ms_cmd_ex('deleteStorageVolume', vol.Name)
       self.assertEqual(ret.ReturnValue, '0', "Volume Delete Failure! Return code not right!")
       
       ret = check_volume_in_system(volname)
       self.assertFalse(ret[0], ret[1])
       
    def test_increase_volume_size(self):
       """
       modifySize<Volume-objID|Volume-ref|Volume-name><new-size-in-bytes>[[user name] [pwd|!]]
       """
       log("test_increase_volume_size")
       volname = self.volprefix+gen_vol_id()
       vol = ms_create_vol(volname=volname, system=self.system)
       self.vollist.append(vol)
       ret = exec_ms_cmd_ex('modifySize', vol.Name, str(get_volume_size(vol)*2))
       self.assertEqual(ret.ReturnValue, '0', "Increase Volume Size Failure! Return code not right!")
       newvol = ms_get_vol('DisplayName', volname)
       self.vollist.remove(vol)
       self.vollist.append(newvol)
       self.assertEqual(get_volume_size(vol)*2, get_volume_size(newvol), "Volume Size Not Match!")
       
    def test_decrease_volume_size(self):
       log("test_decrease_volume_size")
       volname = self.volprefix+gen_vol_id()
       volsize = self.poollist[0].RemainingManagedSpace
       vol = ms_create_vol(volname=volname, size=volsize, system=self.system)
       self.vollist.append(vol)
       newsize = long(volsize)/2
       ret = exec_ms_cmd_ex('modifySize', vol.Name, str(newsize))
       self.assertEqual(ret.ReturnValue, '0', "Decrease Volume Size Failure! Return code not right!")
       newvol = ms_get_vol('DisplayName', volname)
       self.vollist.remove(vol)
       self.vollist.append(newvol)
       self.assertTrue(newsize <= get_volume_size(newvol), "Volume Size Not Match!")
       
    def test_decrease_volume_with_random_size(self):
       log("test_decrease_volume_with_random_size")
       volname = self.volprefix+gen_vol_id()
       volsize = self.poollist[0].RemainingManagedSpace
       vol = ms_create_vol(volname=volname, size=volsize, system=self.system)
       self.vollist.append(vol)
       newsize = random.randint(50, long(volsize)-1)
       ret = exec_ms_cmd_ex('modifySize', vol.Name, str(newsize))
       self.assertEqual(ret.ReturnValue, '0', "Decrease Volume Size Failure! Return code not right!")
       newvol = ms_get_vol('DisplayName', volname)
       self.vollist.remove(vol)
       self.vollist.append(newvol)
       self.assertTrue(newsize <= get_volume_size(newvol), "Volume Size Not Match!")

class MSStorageGroupTest(unittest.TestCase):
    # 
    
    @classmethod
    def setUpClass(self):
       log("MSStorageGroupTest Class SetUp")
       connect_to_win()
       
       self.volprefix = generate_vol_prefix()
       self.poollist = get_pool_sizes()
       self.vollist = []
       self.spclist = []
       self.system = ms_enumerate("MSFT_SMSystem")[0]
       self.hostlist, self.clusterlist = ms_get_unmapped_hosts()
       self.ibmhostlist = ms_cim_enumerate('IBMTSDS_StorageHardwareID')
       close_all_connections()
      
    @classmethod
    def tearDownClass(self):
       for vol in self.vollist:
          try:
             ms_remove_vol(vol)
          except:
             pass
       for spc in self.spclist:
          try:
             ms_remove_spc(spc)
          except:
             pass
       close_all_connections()
      
    def setUp(self):
       connect_to_win()
   
    def tearDown(self):
       raiseflag = False
       while self.vollist:
          vol = self.vollist.pop()
          try:
             ms_remove_vol(vol)
          except:
             raiseflag = True
       while self.spclist:
          spc = self.spclist.pop()
          try:
             ms_remove_spc(spc)
          except:
             raiseflag = True
       close_all_connections()
       if raiseflag:
          raise 
    
    #@unittest.skipIf(not self.hostlist, "no unmapped host found on storage!")
    def test_create_spc(self):
       """
       cssg or createSystemStorageGroup <system-objID> [Name] [LUNames] [DeviceNumbers] 
       [DeviceAccesses] [InitiatorID] [TargetPortID[Replace with TargetPortIDs?]] 
       [HostMode] [[user name] [pwd|!]]
       """
       log("test_create_spc")
       volname = self.volprefix+gen_vol_id()
       vol = ms_create_vol(volname=volname, system=self.system)
       self.vollist.append(vol)
       dn = '1'
       host = random.choice(self.hostlist)
       spc = ms_create_spc(self.system, luns=vol, dn=dn, iid=host.StorageID)
       self.spclist.append(spc)
       check_vol_in_spc(vol, spc)
    
    #@unittest.skipIf(not self.clusterlist, "no unmapped host found on storage!")
    def test_create_cluster_spc(self):
       log("test_create_cluster_spc")
    
    def test_create_spc_without_volume(self):
       log("test_create_spc_without_volume")
       
    def test_create_spc_with_nonexist_iscsi_host(self):
       log("test_create_spc_with_nonexist_iscsi_host")
       
    def test_create_spc_with_nonexist_fc_host(self):
       log("test_create_spc_with_nonexist_fc_host")
    
    def test_add_volume_to_spc(self):
       log("test_add_volume_to_spc")
    
    def test_remove_volume_from_spc(self):
       log("test_remove_volume_from_spc")
    
    def test_remove_spc(self):
       log("test_remove_spc")
    
    def test_remove_initiator(self):
       log("test_remove_initiator")
    
    def test_add_initiator(self):
       log("test_add_initiator")
    
    def test_remove_initiator(self):
       log("test_remove_initiator")
    
    def test_set_device_access(self):
       log("test_set_device_access")
    
    def test_add_ports_to_spc(self):
       log("test_add_ports_to_spc")
    
    def test_remove_ports_from_spc(self):
       log("test_remove_ports_from_spc")
    
    def test_rename_storage_group(self):
       log("test_rename_storage_group")
    
class MSReplicaTest(unittest.TestCase):
    # 
    
    @classmethod
    def setUpClass(self):
       log("MSReplicaTest Class SetUp")
       connect_to_win()
       
#       self.volprefix = generate_vol_prefix()
#       self.poollist = get_pool_sizes()
       self.vollist = []       
#       self.system = ms_enumerate("MSFT_SMSystem")[0]
       close_all_connections()
      
    @classmethod
    def tearDownClass(self):
       log("MSReplicaTest Class TearDown")
       for vol in self.vollist:
          try:
             ms_remove_vol(vol)
          except:
             pass
       close_all_connections()
      
    def setUp(self):
       connect_to_win()
   
    def tearDown(self):
       raiseflag = False
       while self.vollist:
          vol = self.vollist.pop()
          try:
             ms_remove_vol(vol)
          except:
             raiseflag = True
       close_all_connections()
       if raiseflag:
          raise 
       
    def test_create_clone(self):
       pass
    
    def test_create_snapshot(self):
       pass
    
    def test_remove_snapshot(self):
       pass
    
def suite(rcase=None):
    cases = []
    tests = ['test_create_clone', 'test_remove_snapshot']
    testclass = MSReplicaTest
    if rcase:
        tests = rcase
    #set_log_path("_autotestlog.log", redirect=False)
    return unittest.TestSuite(map(testclass, tests))

if __name__ == '__main__':
   #set_log_path(None, "_testlog.log", redirect=True)
   #unittest.main(verbosity=2)
   rsuite = suite()
   unittest.TextTestRunner(verbosity=2).run(rsuite) 